<template>
  <div />
</template>
<script setup lang="ts">
import { useUserStore } from "@/store/modules/user";
import { notify } from "@/utils/wsnotify";
const { VITE_API_URL } = import.meta.env;
let apiBaseUrl = VITE_API_URL;

const props = defineProps({
  uri: {
    type: String,
    default: "/websocket"
  }
});

const state = reactive({
  webSocket: ref(), // webSocket实例
  lockReconnect: false, // 重连锁，避免多次重连
  maxReconnect: 6, // 最大重连次数， -1 标识无限重连
  reconnectTime: 0, // 重连尝试次数
  heartbeat: {
    interval: 30 * 1000, // 心跳间隔时间
    timeout: 10 * 1000 // 响应超时时间
  },
  token: null
});

const initWebSocket = token => {
  // ws地址
  const userStore = useUserStore();
  const url = apiBaseUrl.replaceAll("http", "ws");
  state.token = token;
  const wsUri = `${url}${props.uri}/${userStore.getUserid}?Authorization=${token}`;
  console.log("websocket url", wsUri);
  // 建立连接
  state.webSocket = new WebSocket(wsUri);
  // 连接成功
  state.webSocket.onopen = onOpen;
  // 连接错误
  state.webSocket.onerror = onError;
  // 接收信息
  state.webSocket.onmessage = onMessage;
  // 连接关闭
  state.webSocket.onclose = onClose;
};

const reconnect = () => {
  if (!state.token) {
    return;
  }
  if (
    state.lockReconnect ||
    (state.maxReconnect !== -1 && state.reconnectTime > state.maxReconnect)
  ) {
    return;
  }
  state.lockReconnect = true;
  setTimeout(() => {
    state.reconnectTime++;
    // 建立新连接
    initWebSocket(state.token);
    state.lockReconnect = false;
  }, 5000);
};

/**
 * 连接成功事件
 */
const onOpen = () => {
  state.reconnectTime = 0;
};
/**
 * 连接失败事件
 * @param e
 */
const onError = () => {
  //重连
  reconnect();
};

/**
 * 连接关闭事件
 * @param e
 */
const onClose = () => {
  console.log("websocket", state.webSocket);
  if (state.webSocket) {
    state.webSocket.close();
  }
};

/**
 * 接收服务器推送的信息
 * @param msgEvent
 */
const onMessage = msgEvent => {
  const msgData = msgEvent.data;
  if (msgData) {
    const message = JSON.parse(msgData);
    console.log("websocket receive", message);
    notify(message);
  }
};

defineExpose({
  initWebSocket,
  reconnect,
  onOpen,
  onError,
  onClose,
  onMessage
});
</script>
